Completed
Push — master ( e9293e...9e79e0 )
by Andreas
19:17
created

workflow.js ➔ render   D

Complexity

Conditions 13

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 5
c 0
b 0
f 0
dl 0
loc 7
rs 4.2

How to fix   Complexity   

Complexity

Complex classes like workflow.js ➔ render often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
$(document).ready(function() {
2
    $('body').on('click', '[data-dialog="delete"]', function(event) {
3
        event.preventDefault();
4
        var button = $(this),
5
            dialog = $('<div class="midcom-delete-dialog">'),
6
            spinner = $('<div class="spinner"><i class="fa fa-pulse fa-spinner"></i></div>'),
7
            text = button.data('dialog-text'),
8
            relocate = button.data('relocate'),
9
            action = button.attr('href') || button.data('action'),
10
            options = {
11
                title:  button.data('dialog-heading'),
12
                modal: true,
13
                width: 'auto',
14
                maxHeight: $(window).height(),
15
                buttons: [{
16
                    text: button.text().trim() || button.data('dialog-heading'),
17
                    click: function() {
18
                        if (relocate) {
19
                            $('<form action="' + action + '" method="post" class="midcom-dialog-delete-form">')
20
                                .append($('<input type="submit" name="' + button.data('form-id') + '">'))
21
                                .append($('<input type="hidden" name="referrer" value="' + location.pathname + '">'))
22
                                .hide()
23
                                .prependTo('body');
24
                            $('input[name="' + button.data('form-id') + '"]').click();
25
                        } else {
26
                            var params = {
27
                                referrer: location.pathname
28
                            };
29
                            params[button.data('form-id')] = 1;
30
31
                            $.post(action, params).done(function(message) {
32
                                button.trigger('dialogdeleted', [message]);
33
                                dialog.dialog("close");
34
                                if (   typeof window.parent.$ !== "undefined"
35
                                    && window.parent.$('#midcom-dialog').length > 0 ) {
36
                                    window.parent.$('#midcom-dialog').dialog('close');
37
                                }
38
                            });
39
                        }
40
                    }
41
                }, {
42
                    text: button.data('dialog-cancel-label'),
43
                    click: function() {
44
                        if (   typeof window.parent.$ !== "undefined"
45
                            && window.parent.$('#midcom-dialog').length > 0 ) {
46
                            window.parent.$('#midcom-dialog')
47
                                .nextAll('.ui-dialog-buttonpane')
48
                                .find('.ui-state-disabled')
49
                                .removeClass('ui-state-disabled');
50
                        }
51
                        $(this).dialog("close");
52
                    }
53
                }]
54
            };
55
56
        if ($('.midcom-delete-dialog').length > 0) {
57
            $('.midcom-delete-dialog').remove();
58
        }
59
60
        if (button.data('recursive')) {
61
            dialog.addClass('loading');
62
            options.buttons[0].disabled = true;
63
            $.getJSON(MIDCOM_PAGE_PREFIX + 'midcom-exec-midcom.helper.reflector/list-children.php',
64
                {guid: button.data('guid')},
65
                function (data) {
66
                    function render(carry, item) {
67
                        carry += '<li class="leaf ' + item['class'] + '">' + item.icon + ' ' + item.title;
68
                        if (item.children) {
69
                            carry += item.children.reduce(render, '<ul class="folder_list">') + '</ul>';
70
                        }
71
                        return carry + '</li>';
72
                    }
73
74
                    if (data.length > 0) {
75
                        $('<ul class="folder_list">')
76
                            .append($(data.reduce(render, '')))
77
                            .appendTo($('#delete-child-list'));
78
                    } else {
79
                        dialog.find('p.warning').hide();
80
                    }
81
                    options.buttons[0].disabled = false;
82
83
                    dialog
84
                        .removeClass('loading')
85
                        .dialog('option', 'position', dialog.dialog('option', 'position'))
86
                        .dialog('option', 'buttons', options.buttons)
87
                        .focus();
88
                });
89
        } else {
90
            text = '<p>' + text + '</p>';
91
        }
92
93
        dialog
94
            .css('min-width', '300px') // This should be handled by dialog's minWidth option, but that doesn't work with width: "auto"
95
                                       // Should be fixed in https://github.com/jquery/jquery-ui/commit/643b80c6070e2eba700a09a5b7b9717ea7551005
96
            .append($(text))
97
            .append(spinner)
98
            .appendTo($('body'));
99
100
        make_dialog(dialog, options);
101
    });
102
103
    $('body').on('click', '[data-dialog="dialog"]', function(event) {
104
        event.preventDefault();
105
        if (!$(this).hasClass('active')) {
106
            create_dialog($(this), $(this).find('.toolbar_label').text() || $(this).attr('title') || '', $(this).attr('href'));
107
        }
108
    });
109
110
    $('body').on('click', '[data-dialog="confirm"]', function(event) {
111
        event.preventDefault();
112
        var button = $(this),
113
            dialog = $('<div class="midcom-confirm-dialog">'),
114
            options = {
115
                title:  button.data('dialog-heading'),
116
                modal: true,
117
                width: 'auto',
118
                maxHeight: $(window).height(),
119
                buttons: [{
120
                    text: button.data('dialog-confirm-label'),
121
                    click: function() {
122
                        button.closest('form').submit();
123
                    }
124
                }, {
125
                    text: button.data('dialog-cancel-label'),
126
                    click: function() {
127
                        $(this).dialog("close");
128
                    }
129
                }]
130
            };
131
132
        if ($('.midcom-confirm-dialog').length > 0) {
133
            $('.midcom-confirm-dialog').remove();
134
        }
135
136
        dialog
137
            .css('min-width', '300px') // This should be handled by dialog's minWidth option, but that doesn't work with width: "auto"
138
                                       // Should be fixed in https://github.com/jquery/jquery-ui/commit/643b80c6070e2eba700a09a5b7b9717ea7551005
139
            .append($('<p>' + button.data('dialog-text') + '</p>'))
140
            .appendTo($('body'));
141
        make_dialog(dialog, options);
142
    });
143
    $('body').on('click', '.midcom-workflow-dialog .ui-dialog-buttonpane .ui-button', function() {
144
        var pane = $(this).closest('.ui-dialog-buttonpane'),
145
            iframe = pane.prevAll('#midcom-dialog').find('iframe'),
146
            disabler = function() {
147
                pane.find('.ui-button')
148
                    .addClass('ui-state-disabled');
149
            };
150
151
        if (!$(this).hasClass('dialog-extra-button') && $('form.datamanager2', iframe.contents()).length > 0) {
152
            $('form.datamanager2', iframe.contents()).on('submit', disabler);
153
        } else {
154
            disabler();
155
        }
156
    });
157
});
158
159
function create_dialog(control, title, url) {
160
    if ($('.midcom-workflow-dialog').length > 0) {
161
        $('.midcom-workflow-dialog .ui-dialog-content').dialog('close');
162
    }
163
164
    var dialog, iframe, spinner,
165
        config = {
166
            dialogClass: 'midcom-workflow-dialog',
167
            buttons: [],
168
            title: title,
169
            height:  590,
170
            width: 800,
171
            close: function() {
172
                control.removeClass('active');
173
                iframe.css('visibility', 'hidden');
174
                if (iframe[0].contentWindow) {
175
                    iframe[0].contentWindow.stop();
176
                }
177
            },
178
            open: function() {
179
                dialog.closest('.ui-dialog').focus();
180
            }};
181
182
    if (control.data('dialog-cancel-label')) {
183
        config.buttons.push({
184
            text: control.data('dialog-cancel-label'),
185
            click: function() {
186
                $(this).dialog( "close" );
187
            }
188
        });
189
    }
190
191
    if ($('#midcom-dialog').length > 0) {
192
        dialog = $('#midcom-dialog');
193
        iframe = dialog.find('> iframe');
194
        spinner = dialog.find('> i').show();
195
        config.height = dialog.dialog('option', 'height');
196
        config.width = dialog.dialog('option', 'width');
197
        if (   config.width > window.innerWidth
198
            || config.height > window.innerHeight) {
199
            config.position = { my: "center", at: "center", of: window, collision: 'flipfit' };
200
        }
201
    } else {
202
        spinner = $('<i class="fa fa-pulse fa-spinner"></i>');
203
        iframe = $('<iframe name="datamanager-dialog"'
204
                   + ' frameborder="0"'
205
                   + ' marginwidth="0"'
206
                   + ' marginheight="0"'
207
                   + ' width="100%"'
208
                   + ' height="100%"'
209
                   + ' scrolling="auto" />')
210
           .on('load', function() {
211
               // this is only here as fallback in case dialog.js doesn't run for whatever reason
212
               spinner.hide();
213
               this.style.visibility = 'visible';
214
           });
215
216
        dialog = $('<div id="midcom-dialog"></div>')
217
            .append(spinner)
218
            .append(iframe)
219
            .on('dialogcreate', function() {
220
                var maximized = false,
221
                    saved_options = {};
222
                $(this).prevAll('.ui-dialog-titlebar').on('dblclick', function() {
223
                    if (!maximized) {
224
                        saved_options.position = dialog.dialog('option', 'position');
225
                        saved_options.width = dialog.dialog('option', 'width');
226
                        saved_options.height = dialog.dialog('option', 'height');
227
                        dialog.dialog('option', {
228
                            width: '99%',
229
                            height: $(window).height(),
230
                            position: {my: 'center top', at: 'center top', of: window}
231
                        });
232
                        maximized = true;
233
                    } else {
234
                        dialog.dialog('option', {
235
                            height: saved_options.height,
236
                            width: saved_options.width,
237
                            position: saved_options.position
238
                        });
239
                        maximized = false;
240
                    }
241
                });
242
            })
243
            .appendTo($('body'));
244
    }
245
246
    config.height = Math.min(config.height, window.innerHeight);
247
    config.width = Math.min(config.width, window.innerHeight);
248
249
    if (url) {
250
        iframe.attr('src', url);
251
    }
252
253
    control.addClass('active');
254
    if (   control.parent().attr('role') === 'gridcell'
255
        && control.closest('.jqgrow').hasClass('ui-state-highlight') === false) {
256
        //todo: find out why the click doesn't bubble automatically
257
        control.parent().trigger('click');
258
    }
259
260
    make_dialog(dialog, config);
261
    dialog.dialog("instance").uiDialog.draggable("option", "containment", false);
262
}
263
264
function make_dialog(node, config) {
265
266
    if (!config.hasOwnProperty('buttons')) {
267
        config.buttons = [];
268
    }
269
    if (config.buttons.length === 0) {
270
        // This is not ideal, but otherwise buttons added by dialog.js are not rendered
271
        config.buttons.push({
272
            text: '...',
273
            click: function() {},
274
            css: {visibility: 'hidden'}
275
        });
276
    }
277
278
    var backup = false;
279
280
    if (typeof($.fn.popover) != 'undefined') {
281
        backup = $.button;
282
        $.widget.bridge("button", $.ui.button);
283
    }
284
285
    node.dialog(config);
286
287
    if (backup) {
288
        $.button = backup;
289
    }
290
}
291